import { Scope } from 'lib/scopeFactory'
import ApiFactory from 'lib/ApiFactory'
import $ from 'jquery'
import DateRangeStore from '../common/DateRangeStore.es6'
import moment from 'moment'
import numeral from 'numeral'
import _ from 'underscore'
import dispatcher from 'lib/dispatcher'
import format from 'lib/util/format'

// import {coreApi,sortMap,parseToChart,parseToTopbar} from '../apis/core-util'


let defaultFetcher = ApiFactory({
  url: (params) => {
    return BlueWare.urlPrefix + '/app/' + params.appId + '/' + params.segment + '/' + params.action + '.json';
  },
  optionParams: ['appId','segment','action'],
  params: {
    appId: {
      defaultValue: BlueWare.appId
    },
    segment: {
      defaultValue: 'basicinfo'
    },
    action: {
      defaultValue: 'appversion'
    }
  }
});

let hourConverter = (hour) => {
  return moment().startOf('day').add(hour, 'hours').valueOf();
}

let resolveData = (rawData) => {
  let startNums = [];
  for (let i = 0; i < rawData.length; i++) {
    startNums.push(rawData[i].startNum);
  }

  let arr2 = [];
  for (let i = 0; i < startNums.length-1; i++) {
    arr2.push(startNums[i] + startNums[i+1]);
  }
  let sum = _.chain(startNums).map(parseFloat).reduce((x, y) => x + y).value();
  let maxer = Math.max.apply(null, arr2);
  let miner = Math.min.apply(null, arr2);
  let ind_maxer = arr2.indexOf(maxer);
  let ind_miner = arr2.indexOf(miner);
  let busy_period = moment(ind_maxer, 'HH').format('HH:mm') + '~' + moment(ind_maxer+2, 'HH').format('HH:mm');
  let idle_period = moment(ind_miner, 'HH').format('HH:mm') + '~' + moment(ind_miner+2, 'HH').format('HH:mm');
  let busy_rate;
  let idle_rate;
  if (!sum) {
    busy_period = '--';
    busy_rate = '--';
    idle_period = '--';
    idle_rate = '--';
  }
  else {
    busy_rate = numeral(parseFloat(maxer/sum)).format('00[.]00%');
    idle_rate = numeral(parseFloat(miner/sum)).format('00[.]00%');
  }
  return [
    {
      busy_period: busy_period,
      busy_rate: busy_rate
    },
    {
      idle_period: idle_period,
      idle_rate: idle_rate
    }
    ];
};

export default class RootScope extends Scope {
  constructor () {
    super();
    this._cache = {}
    this.$state = {
      versions: [],
      channels: [],
      chart0DataSource:{
        origin:null,
        comparer:null
      },
      aliveUserComparer:{},
      aliveNumComparer:{},
      startNumComparer:{},
      chart1DataSource:{
        origin:null,
        comparer1:null,
        comparer2:null
      },
      chart0: {
        loading: true
      },
      chart1_1: {
        loading: true
      },
      chart1_1_tooltipFormat:function (tooltip){
        let tmpl
        let pattern = 'HH:mm'
        if(this.points&&this.points.length){
          let serieTmpl = _.template('<i class="iconfont  state-downtime" style="color:<%=series.color%>">● </i> <%=series.name%> 期间内的<%=tooltipName%>为 <%=customData.y.fmtVal%><br />');

          tmpl = (
            '从 '
          + moment(this.points[0].point.customData.startTime).format(pattern)
          + ' 到 ' + moment(this.points[0].point.customData.endTime).format(pattern)
          + ' 的' + moment.duration(this.points[0].point.customData.endTime - this.points[0].point.customData.startTime).humanize()
          + '内'
          + '<br/>'
          + _(this.points).map(function(item){ return serieTmpl(item.point) }).join('')
          )
          return _.template(tmpl)(this.points[0]);
        }
        return null
      },
      chart1_2: {
        loading: true
      },
      grid:{
        loading:true
      },
      grid1_1:{
        loading:true
      },
      grid1_2:{
        loading:true
      },
      duration: () => moment.duration(DateRangeStore.getValue().spanTime),
      dayTypeState: 'daily',
      filterList: [],
      chart0Key: null,
      chart1_1Key: null,
      chart1_2Key: null

      // totalNum:0,
      // dayState:'day',
      // currentTab:1,
      // chart_active_user:{
      //   loading:true
      // },
      // chart_active_period:{
      //   loading:true
      // }
    };

    this.recalcChart0Key();

    // DateRangeStore.setDefaultItem({
    //   spanTime: moment.duration(7, 'days').valueOf(),
    //   endTime: moment().startOf('day').add(1, 'days').valueOf()
    // });

    let self = this;

    this.versions = defaultFetcher({
    });
    this.channels = defaultFetcher({
      action: 'appChannel'
    });

    this.chart0Api = defaultFetcher({
      segment: 'useranalysis',
      action: 'useralive',
      timeUnit: () => self.$state.dayTypeState,
      appVersionId: () => {
        let target = _.find(this.$state.filterList, item => item.type === 'version');

        return target ? target.value : undefined;
      },
      channel: () => {
        let target = _.find(this.$state.filterList, item => item.type === 'channel');

        return target ? target.value : undefined;
      }
    }, DateRangeStore.getValue);
    this.chart0Comparer = defaultFetcher({
      segment: 'useranalysis',
      action: 'useralive',
      timeUnit: () => self.$state.dayTypeState,
      appVersionId: () => {
        let target = _.find(this.$state.filterList, item => item.type === 'version');

        return target ? target.value : undefined;
      },
      channel: () => {
        let target = _.find(this.$state.filterList, item => item.type === 'channel');

        return target ? target.value : undefined;
      }
    });

    this.chart1Api = defaultFetcher({
      segment: 'useranalysis',
      action: 'userhourlyalive',
      timeUnit: () => self.$state.dayTypeState,
      appVersionId: () => {
        let target = _.find(this.$state.filterList, item => item.type === 'version');

        return target ? target.value : undefined;
      },
      channel: () => {
        let target = _.find(this.$state.filterList, item => item.type === 'channel');

        return target ? target.value : undefined;
      }
    }, DateRangeStore.getValue);
    this.chart1Comparer = defaultFetcher({
      segment: 'useranalysis',
      action: 'userhourlyalive',
      timeUnit: () => self.$state.dayTypeState,
      appVersionId: () => {
        let target = _.find(this.$state.filterList, item => item.type === 'version');

        return target ? target.value : undefined;
      },
      channel: () => {
        let target = _.find(this.$state.filterList, item => item.type === 'channel');

        return target ? target.value : undefined;
      }
    });

  } // constructor

  convertChart0OriginSeries(json) {
    return {
      id: 0,
      name: DateRangeStore.getDisplayText(),
      data: _.map(json, (item) => {
        return {
          x: item.startTime,
          y: item.val,
          customData: {
            y: {
              label: '活跃用户',
              fmtVal: item.val
            },
            startTime: item.startTime,
            endTime: item.endTime
          }
        };
      })
    };
  }

  $load_data () {
    let version = _.find(this.$state.filterList, item => item.type === 'version');
    this.$state.versionFilter = version ? version.value : null;

    let target = _.find(this.$state.filterList, item => item.type === 'channel');
    this.$state.channelFilter = target ? target.value : null;

    this.$state.aliveUserComparer = {};

    this.chart0Api.fetch().then((json) => {
      this.recalcChart0Key();

      this.$state.chart0DataSource.origin = json;

      let reversedJson = _.filter(json, item => true).reverse();

      this.$state.grid = {
        data: _.filter(reversedJson, (value, index) => index < 10),
        showMore: () => {
          let deferred = $.Deferred();
          setTimeout(() => {
            let list = _.filter(this.$state.grid._data, (value, i) => i < 10);
            this.$state.grid._data = _.filter(this.$state.grid._data, (value, i) => i >= 10);

            deferred.resolve({
              data: list,
              hasMore: this.$state.grid._data.length > 0
            });
          }, 300);
          return deferred.promise();
        },
        _data: _.filter(reversedJson, (value, i) => i >= 10),
        _originalData: reversedJson
      };
      this.$state.grid.hasMore = this.$state.grid._data.length > 0;

      this.$state.chart0 = {
        data: {
          yAxis: {
            labels: {
              formatter:function(){
                return format.integer(this.value)
              }
            },
            maxPadding: 0,
            tickPositioner: function() {
              let positions = [0];
              if (this.dataMax === 0) {
                return positions;
              }

              let maxValue = (this.dataMax % 2) === 1
                               ? (this.dataMax + 1)
                               : this.dataMax;
              let increment = maxValue / 2;

              for (let i = 1; i * increment <= maxValue; i++) {
                  positions.push(i * increment);
              }
              return positions;
            }
          },
          series: [this.convertChart0OriginSeries(json)]
        }
      };

      dispatcher.dispatch({
        $type: 'reset_date_comparer'
      });

      this.emit();
    }, () => {}, () => {
      this.$state.chart0 = {
        loading:true
      }
    })

    /* chart 1 && 2 */
    this.chart1Api.fetch().done((json) => {
      this.recalcChart1_1Key();
      this.recalcChart1_2Key();

      this.$state.chart1DataSource.origin = json;
      this.$state.chart1DataSource.comparer = null;

      let span = moment.duration(1, 'hours').valueOf();

      let series1_1_0 = {
        id: 0,
        name: DateRangeStore.getDisplayText(),
        data: _.map(json, (item) => {
          let begin = hourConverter(item.hour);
          return {
            x: begin,
            y: item.aliveNum,
            tooltipName:'活跃用户数',
            customData: {
              y: {
                label: '活跃用户',
                fmtVal: item.aliveNum
              },
              startTime: begin,
              endTime: begin + span
            }
          };
        })
      };
      this.$state.chart1_1 = {
        data: {
          yAxis: {
            labels: {},
            maxPadding: 0,
            minTickInterval: 1
          },
          series: [series1_1_0]
        }
      };

      let series1_2_0 = {
        id: 0,
        name: DateRangeStore.getDisplayText(),
        data: _.map(json, (item) => {
          let begin = hourConverter(item.hour);
          return {
            x: begin,
            y: item.startNum,
            tooltipName:'启动次数',
            customData: {
              y: {
                label: '启动次数',
                fmtVal: item.startNum
              },
              startTime: begin,
              endTime: begin + span
            }
          };
        })
      };
      this.$state.chart1_2 = {
        data: {
          yAxis: {
            labels: {},
            maxPadding: 0,
            minTickInterval: 1
          },
          series: [series1_2_0]
        }
      };

      this.$state.grid1_1 = {
        data: [resolveData(json)[0]]
      };
      this.$state.grid1_2 = {
        data: [resolveData(json)[1]]
      };


      // dispatcher.dispatch({
      //   $type: 'reset_date_comparer'
      // });

      this.emit();
    }).fail((err) => {
      console.log(err);
    });


  } // $load_data

  $filter_check (payload) {
    let targetItem = _.find(this.$state.filterList, item => item.type === payload.filterType);
    if(targetItem) {
      _.extend(targetItem, payload.target);
    } else {
      this.$state.filterList.push(_.extend({type: payload.filterType}, payload.target));
    }

    this.emit();
  }

  $day_type_changed (payload) {
    this.$state.dayTypeState = payload.newType;
    this.$load_data();
  }

  $settime(payload){
    this.$state.dayTypeState = 'daily';
    this.$load_data();
  }

  $load() {
    this.versions.fetch().done((json) => {
      this.$state.versions = json.result;
      this.emit();
    }).fail((err) => {
      console.log(err);
    });

    this.channels.fetch().done((json) => {
      this.$state.channels = json.result;
      this.emit();
    }).fail((err) => {
      console.log(err);
    });

    this.$load_data();
  }

  $compare_date_range(payload) {
    if (payload.id === 'aliveUser') {

      this.$state.aliveUserComparer = payload.data;

      // Tab1: 活跃用户 - 活跃用户
      this.chart0Comparer.fetch((ajaxOptions) => {
        _.extend(ajaxOptions.data, {
          spanTime: payload.data.spanTime,
          endTime: payload.data.endTime
        });
        return ajaxOptions;
      }).done((json) => {

        this.$state.chart0DataSource.comparer = json;

        let spanTime = this.$state.chart0.data.series[0].data[0].x - json[0].startTime;

        let series0_1 = {
          id: 1,
          name: payload.data.displayText,
          data: _.map(json, (item) => {
            return {
              x: item.startTime + spanTime,
              y: item.val,
              customData: {
                y: {
                  label: '活跃用户',
                  fmtVal: item.val
                },
                startTime: item.startTime,
                endTime: item.endTime
              }
            };
          })
        };
        this.$state.chart0.data.series = [
          // this.$state.chart0.data.series[0],
          this.convertChart0OriginSeries(this.$state.chart0DataSource.origin),
          series0_1
        ];
        this.emit();
      });
    } else if (payload.id === 'aliveNum') {
      // Tab2: 活跃时段 - 活跃用户
      this.$state.aliveNumComparer = payload.data;

      this.chart1Comparer.fetch((ajaxOptions) => {
        _.extend(ajaxOptions.data, {
          spanTime: payload.data.spanTime,
          endTime: payload.data.endTime
        });
        return ajaxOptions;
      }).done((json) => {

        this.$state.chart1DataSource.comparer1 = json;

        let span = moment.duration(1, 'hours').valueOf();

        let series1_1 = {
          id: 0,
          name: payload.data.displayText,
          data: _.map(json, (item) => {
            let begin = hourConverter(item.hour);
            return {
              x: begin,
              y: item.aliveNum,
              tooltipName:'活跃用户数',
              customData: {
                y: {
                  label: '活跃用户',
                  fmtVal: item.aliveNum
                },
                startTime: begin,
                endTime: begin + span
              }
            };
          })
        };
        this.$state.chart1_1.data.series = [
          this.$state.chart1_1.data.series[0],
          series1_1
        ];
        this.emit();
      });
    } else if (payload.id === 'startNum') {
      // Tab2: 活跃时段 - 启动次数
      this.$state.startNumComparer = payload.data;

      this.chart1Comparer.fetch((ajaxOptions) => {
        _.extend(ajaxOptions.data, {
          spanTime: payload.data.spanTime,
          endTime: payload.data.endTime
        });
        return ajaxOptions;
      }).done((json) => {

        this.$state.chart1DataSource.comparer2 = json;

        let span = moment.duration(1, 'hours').valueOf();

        let series1_2 = {
          id: 0,
          name: payload.data.displayText,
          data: _.map(json, (item) => {
            let begin = hourConverter(item.hour);
            return {
              x: begin,
              y: item.startNum,
              tooltipName:'启动次数',
              customData: {
                y: {
                  label: '启动次数',
                  fmtVal: item.startNum
                },
                startTime: begin,
                endTime: begin + span
              }
            };
          })
        };
        this.$state.chart1_2.data.series = [
          this.$state.chart1_2.data.series[0],
          series1_2
        ];
        this.emit();
      });
    }
  } // $compare_date_range

  recalcChart0Key() {
    this.$state.chart0Key = new Date().getTime();
  }
  recalcChart1_1Key() {
    this.$state.chart1_1Key = new Date().getTime();
  }
  recalcChart1_2Key() {
    this.$state.chart1_2Key = new Date().getTime();
  }

  $remove_filter(payload) {
    this.$state.filterList = _.filter(this.$state.filterList, item => item.type !== payload.target.type);

    this.emit();
  }
}
